package com.sanbi.common.util;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import lombok.SneakyThrows;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

public class GraphicCodeUtil {
    /**
     * @desc 生成 ean-13 条形码
     * @author wanggang
     * @time 2022/10/24 14:34
     */
    @SneakyThrows
    public static void generateBarCode(String contents, int width, int height, String imgPath) {
        int codeWidth = 3 + // start guard
                (7 * 6) + // left bars
                + // middle guard
                        (7 * 6) + // right bars
                3; // end guard
        codeWidth = Math.max(codeWidth, width);
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,BarcodeFormat.EAN_13, codeWidth, height, null);
            MatrixToImageWriter.writeToFile(bitMatrix, "png", new File(imgPath));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @SneakyThrows
    public static void generateQrCode(String content, String filepath) {
        int width = 200;
        int height = 200;
        Map<EncodeHintType, Object> encodeHints = new HashMap<EncodeHintType, Object>();
        encodeHints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, encodeHints);
        Path path = FileSystems.getDefault().getPath(filepath);
        MatrixToImageWriter.writeToPath(bitMatrix, "png", path);
    }

    @SneakyThrows
    public static String readGraphicCode(String filepath) {
        BufferedImage bufferedImage = ImageIO.read(new FileInputStream(filepath));
        LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
        Binarizer binarizer = new HybridBinarizer(source);
        BinaryBitmap bitmap = new BinaryBitmap(binarizer);
        HashMap<DecodeHintType, Object> decodeHints = new HashMap<DecodeHintType, Object>();
        decodeHints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        Result result = new MultiFormatReader().decode(bitmap, decodeHints);
        return result.getText();
    }

    private static boolean checkStandardUPCEANChecksum(CharSequence s) throws FormatException {

        int length = s.length();

        if (length == 0) {

            return false;

        }

        int sum = 0;

        for (int i = length - 2; i >= 0; i -= 2) {

            int digit = (int) s.charAt(i) - (int) '0';

            if (digit < 0 || digit > 9) {

                throw FormatException.getFormatInstance();

            }

            sum += digit;

        }

        sum *= 3;

        for (int i = length - 1; i >= 0; i -= 2) {

            int digit = (int) s.charAt(i) - (int) '0';

            if (digit < 0 || digit > 9) {

                throw FormatException.getFormatInstance();

            }

            sum += digit;

        }

        return sum % 10 == 0;

    }

    public static void main(String[] args) throws FormatException {
        String content = "6901234567891";
//        String path = "C:\\\\Users\\\\23026\\\\Desktop\\\\tempQrcode\\";
        String path = "C:\\Users\\admin\\Pictures\\tempQrcode\\";
//        String fileName=String.format("%s%s.png",path, (new Date()).getTime());
        String fileName=String.format("%s%s.png",path, System.currentTimeMillis());

//        generateQrCode(content,fileName);
        if(checkStandardUPCEANChecksum(content)){
            generateBarCode(content,300,100,fileName);
            System.out.println("ok: "+fileName);
        }
        generateBarCode(content,300,100,fileName);
        System.out.println("ok: "+fileName);

        System.out.println("wrong: "+fileName);

//        String finalFile=readGraphicCode(fileName);
//        System.out.println("read: "+finalFile);
    }
}
